import _ from 'lodash';
import validator from 'validator';
import Promise from 'promise';
import config from '../config';
import * as at from '../common/at';
import * as cache from '../common/cache';
import * as message from '../common/message';
import getPages from '../common/pages';
import * as ResultMsg from '../constrants/ResultMsg';
import { errorJson, successJson } from '../common/response';
import { checkId, checkDoc } from '../common/check';
import { UserProxy, TopicProxy, ReplyProxy } from '../proxy';

export {
  replies,
  add,
  del,
  update,
  up,
};

async function replies(req, res, next) {
  const appId = res.locals.appId;
  const topicId = req.params.tid;
  const currentPage = parseInt(req.body.currentPage, 10) || 1;
  const conditions = { topic_id: topicId, deleted: false };
  const limit = config.list_reply_count;
  const options = { skip: (currentPage - 1) * limit, limit, sort: 'create_at' };

  try {
    const count = await getPages(ReplyProxy.count, conditions, '[reply pages]');
    const pages = Math.ceil(count / limit);
    const replies = await ReplyProxy.find(appId, conditions, options);

    let replyAuthorIds = [];

    replies.forEach((item) => {
      if (item.author_id) replyAuthorIds.push(item.author_id.toString());
    });

    replyAuthorIds = _.uniq(replyAuthorIds);
    const authors = await UserProxy.findByIds(appId, replyAuthorIds);
    successJson(req, res, { data: { currentPage, replies, authors, pages } });
  } catch (err) {
    next(err);
  }
}

async function add(req, res, next) {
  const appId = res.locals.appId;
  const content = validator.trim(String(req.body.content || ''));
  const topicId = req.params.tid;
  const replyId = req.body.reply_id || '';
  const authorId = req.session.user._id;

  if (content === '' || content.length <= 3) {
    return errorJson(req, res, { err: '回复内容太少' });
  }

  if (!topicId || !authorId) {
    return errorJson(req, res, { err: '参数错误' });
  }

  let data = {
    authorId,
    replyId,
    topicId,
    content
  };

  try {
    const topic = await TopicProxy.findOneById(appId, topicId);
    if (!topic) return errorJson(req, res, { err: '文章不存在' });
    let reply = await ReplyProxy.create(appId, data);
    await TopicProxy.updateLastReply(appId, topicId, reply._id);

    at.sendMessageToMentionUsers(appId, content, topicId, authorId, reply._id);
    await message.sendReplyMessage(appId, topic.author_id, authorId, topicId, reply._id);

    const author = await UserProxy.increaseScore(appId, authorId, { replyCount: 1 });
    reply = reply.toObject();
    reply.author = author;
    successJson(req, res, { data: { reply } });
  } catch (err) {
    next(err);
  }
}

async function del(req, res, next) {
  const appId = res.locals.appId;
  const replyId = req.body.reply_id;
  const userId = req.session.user._id.toString();

  try {
    await checkId(replyId);
    const reply = await ReplyProxy.findOneById(appId, replyId);

    if (reply.author_id.toString() !== userId && !req.session.user.is_admin) {
      return errorJson(req, res, { err: '没有权限' });
    }

    const data = {
      deleted: true,
    };

    await ReplyProxy.update(appId, replyId, data);
    const lastReplyId = await ReplyProxy.getLastReplyIdByTopicId(appId, reply.topic_id);
    await TopicProxy.reduceTopicCount(appId, reply.topic_id, lastReplyId);
    successJson(req, res, { msg: '删除成功' });
  } catch (err) {
    next(err);
  }
}

async function update(req, res, next) {
  const appId = res.locals.appId;
  const replyId = req.params.reply_id;
  const content = req.body.content;
  const userId = req.session.user._id.toString();

  if (content.trim().length <= 3) {
    return errorJson(req, res, { err: '回复字数太少' });
  }

  try {
    const reply = await ReplyProxy.findOneById(appId, replyId);

    if (reply.author_id.toString() !== userId && !req.session.user.is_admin) {
      return errorJson(req, res, { err: '没有权限' });
    }

    const data = {
      content,
    };

    await ReplyProxy.update(appId, replyId, data);
    successJson(req, res, { msg: '更新成功' });
  } catch (err) {
    next(err);
  }
}

async function up(req, res, next) {
  const appId = res.locals.appId;
  const replyId = req.params.reply_id;
  const userId = req.session.user._id;

  try {
    await checkId(replyId);
    const reply = await ReplyProxy.findOneById(appId, replyId);

    if (reply.author_id.toString() === userId && !req.session.user.is_admin) {
      return errorJson(req, res, { err: '不能帮自己点赞' });
    }

    const upIndex = reply.ups.indexOf(userId);

    const data = {
      ups: upIndex < 0 ? reply.ups.push(userId) : replies.ups.splice(upIndex, 1),
    };

    await ReplyProxy.update(appId, replyId, data);
    const msg = upIndex < 0 ? '点赞成功' : '取消点赞';
    successJson(req, res, { msg });
  } catch (err) {
    next(err);
  }
}
